package edu.rit.varapp.datalayer;

import edu.rit.varapp.db.DatabaseConnection;
import edu.rit.varapp.logging.Logging;
import edu.rit.varapp.utilities.ExceptionUtils;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 *
 * @author Eric Kisner
 */
public class Post {

    private DatabaseConnection conn;
    private static PreparedStatement retrievePS = null;

    public Post() {
        this.conn = DatabaseConnection.instance();
        initPreparedStatement();
    }

    /**
     * Initialize a prepared statement which will be used every time we get messages for a
     * specified customer.
     */
    private void initPreparedStatement() {
        try {
            retrievePS = conn.newPreparedStatement( "SELECT * FROM messages WHERE EntityID = ?" );
        } catch( SQLException sqle ) {
            Logging.log( "Problem initializing a Prepared Statement, exception details follow." );
            ExceptionUtils.handleException( sqle, this.getClass() );
            System.exit( 1 );
        }
    }

    /**
     * Deletes a specific message.
     * @param m The message to delete.
     * @return True if the message has been delete, else false.
     * @throws SQLException
     */
    public boolean deleteMessage( int messageId ) throws SQLException {
        String sql = "DELETE FROM messages WHERE messageId = " + messageId;
        int updated = conn.executeUpdateQuery( sql );
        if( updated > 0 ) {
            return true;
        }
        return false;
    }

    /**
     * Updates a message's "status" by marking it to 'Read'.
     * @param m The message whose status we are changing.
     * @throws SQLException
     */
    public void updateMessageStatus( Message m ) throws SQLException {
        //A message can only be updated to have status of 'Read', so we can just change it to that
        String sql = "UPDATE messages SET status = '" + Message.READ + "' WHERE messageId = " + m.getMessageId();
        //User doesn't need to know that the status has been set to 'Read'
        conn.executeUpdateQuery( sql );
    }

    /**
     * Retrieves a message based on a datetime.
     * @param date The datetime the message was posted.
     * @return The message that was posted on the specified datetime.
     */
    public Message retrieveMessage( String datetime ) throws SQLException {
        Message ret = null;
        String sql = "SELECT * FROM messages WHERE Date = '" + datetime + "'";
        ResultSet rs = conn.executeQuery( sql );
        if( rs.next() ) {
            ret = buildMessage( conn.getSingleRow( rs ) );
        }
        return ret;
    }

    /**
     * Retrieves all message based on the customer's ID.
     * @param entityId The customer's ID
     * @return A list of messages sent to the specific customer.
     */
    public ArrayList<Message> retrieveMessages( int entityId ) throws SQLException {
        ArrayList<Message> ret = new ArrayList<Message>();
        retrievePS.setInt( 1, entityId );
        ResultSet rs = retrievePS.executeQuery();
        ArrayList<ArrayList<String>> data = conn.getData( rs, false );

        for( ArrayList<String> row : data ) {
            ret.add( buildMessage( row ) );
        }
        return ret;
    }

    /**
     * Inserts a new message into the database.
     * @param m The message to insert.
     * @return True if the insert was successful, else false.
     */
    public boolean insertMessage( Message m ) throws SQLException {
        String sql = "INSERT INTO messages ( " + Message.columnsToSQL() + " ) "
                     + "VALUES ( " + m.valuesToSQL() + " )";
        int updated = conn.executeUpdateQuery( sql );
        if( updated > 0 ) {
            return true;
        }
        return false;
    }

    private Message buildMessage( ArrayList<String> data ) {
        return new Message( Integer.parseInt( data.get( 0 ) ),
                            Integer.parseInt( data.get( 1 ) ),
                            data.get( 2 ),
                            data.get( 3 ),
                            data.get( 4 ),
                            data.get( 5 ).charAt( 0 ) );

    }
}
